/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package pessoas.presenter;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import static java.lang.Thread.sleep;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
import pessoas.collection.Contatos;
import pessoas.collection.ContatosInvalidos;
import pessoas.collection.Operadoras;
import pessoas.dataHora.DataHora;
import pessoas.mementoContato.Contato;
import pessoas.model.Usuario;
import pessoas.serializacao.serializacaoArquivo;
import pessoas.view.ImportacaoXMLView;

/**
 *
 * @author Bush
 */
public class ImportacaoXMLPresenter {

    private ImportacaoXMLView view;
    private Contatos contatos;
    private String caminho;
    private DefaultTableModel tm;
    private ContatosInvalidos contatosInvalidos;
    private boolean carregando = true;
    private int numLinhas = 0;
    private Operadoras operadoras;
    private Usuario usuario;
    private serializacaoArquivo serializacao;
    private DataHora dataHora;

    public ImportacaoXMLPresenter(Usuario usu, final Contatos contatos,ContatosInvalidos contatosInvalidos) {
        view = new ImportacaoXMLView(null, true);
        this.contatos = contatos;
        this.usuario = usu;
        this.contatosInvalidos = contatosInvalidos;
        serializacao = new serializacaoArquivo();
        dataHora = new DataHora();
        try {
            this.operadoras = Operadoras.getInstancia();
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage());
        }
        caminho = "";

        view.getBtnFechar().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                view.dispose();
            }
        });

        view.getBtnImportar().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                new Thread() {
                    public void run() {
                        //int i = 0;
                        try {
                            view.getBarraProgresso().setMaximum(serializacao.tamanhoArquivo(caminho));
                        } catch (IOException ex) {
                            JOptionPane.showMessageDialog(null, ex.getMessage());
                        }
                        while (carregando) {
                            try {
                                sleep(100);
                                view.getBarraProgresso().setValue(numLinhas);
                            } catch (InterruptedException ex) {
                                JOptionPane.showMessageDialog(null, ex.getMessage());
                            }

                        }
                    }
                }.start();
                new Thread() {
                    public void run() {
                        try {
                            importar();
                        } catch (FileNotFoundException ex) {
                            JOptionPane.showMessageDialog(null, ex.getMessage());
                        } catch (IllegalAccessException ex) {
                            JOptionPane.showMessageDialog(null, ex.getMessage());
                        } catch (InstantiationException ex) {
                            JOptionPane.showMessageDialog(null, ex.getMessage());
                        } catch (ClassNotFoundException ex) {
                            JOptionPane.showMessageDialog(null, ex.getMessage());
                        } catch (IOException ex) {
                            JOptionPane.showMessageDialog(null, ex.getMessage());
                        }
                    }
                }.start();
            }
        });

        view.getBtnProcurar().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                escolherArquivo();
            }

        });

        view.setLocationRelativeTo(view);
        view.setVisible(true);
    }

    public ImportacaoXMLView getView() {
        return view;
    }

    public void escolherArquivo() {
        JFileChooser fc = new JFileChooser();
        int res = fc.showOpenDialog(null);
        try {
            if (res == JFileChooser.APPROVE_OPTION) {
                File arquivo = fc.getSelectedFile();
                caminho = arquivo.getPath();
                if (caminho.contains(".xml")) {
                    view.getBtnProcurar().setText(arquivo.getName());
                } else {
                    throw new Exception("Formato invalido!\nInforme um arquivo .xml válido!");
                }
            } else {
                throw new Exception("Voce nao selecionou nenhum arquivo");
            }
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage());
        }
    }

    public void carregaTabela(ArrayList<Contato> c) {
        tm = new DefaultTableModel(
                new Object[][]{},
                new String[]{"Nome", "Sobrenome", "Telefone", "Uf", "Operadora"}) {

                    @Override
                    public boolean isCellEditable(int row, int col) {
                        return false;
                    }
                };
        tm.setNumRows(0);
        for (int i = 0; i < c.size(); i++) {
            String contato = c.get(i).toString();
            String linha[] = contato.split(",");
            tm.addRow(linha);
        }
        view.getTabela().setModel(tm);
    }

//----------------------- Métodos de Verificação de Dados XML Importados------------------------------
    public ArrayList<Contato> verificacaoDeImportacao(ArrayList<Contato> contatosImp) throws Exception {
        ArrayList<Contato> contatosValidos = new ArrayList<Contato>();
        int contAnts = contatosInvalidos.getContatosInvalidos().size();
        int contatosExistentes = 0;
        for (int i = 0; i < contatosImp.size(); i++) {
            if (!contatos.verificaContato(contatosImp.get(i)) && !contatos.verificaContatoArray(contatosImp, contatosImp.get(i))) {
                if (!operadoras.dddExiste(contatosImp.get(i).getTelefone().substring(1, 3))
                        || !operadoras.prefixoExiste(contatosImp.get(i).getTelefone().substring(1, 3), contatosImp.get(i).getTelefone().substring(4, 6))) {
                    contatosInvalidos.getContatosInvalidos().add(contatosImp.get(i));
                } else {
                    contatosImp.set(i, operadoras.detectaUfOperadora(contatosImp.get(i)));
                    contatosValidos.add(operadoras.detectaUfOperadora(contatosImp.get(i)));
                }
            } else {
                contatosExistentes++;
                contatosImp.remove(i);
            }
        }
        view.getTxtSucedido().setText(String.valueOf(contatosValidos.size()));

        if (contatosExistentes > 0) {
            view.getTxtExistentes().setText(String.valueOf(contatosExistentes));
        }

        carregaTabela(contatosImp);

        if (contatosInvalidos.getContatosInvalidos().size() > 0) {
            view.getTxtInvalidos().setText(String.valueOf(contatosInvalidos.getContatosInvalidos().size() - contAnts));
            for (int i = 0; i < contatosInvalidos.getContatosInvalidos().size(); i++) {
                serializacao.gravaContatoInvalido(contatosInvalidos.getContatosInvalidos().get(i));
            }
            if (JOptionPane.showConfirmDialog(null, "Deseja alterar os contatos Inválidos?") == 0) {
                new ContatosInvalidosPresenter(usuario, contatos, contatosInvalidos);
            }
        }
        contatos.gravarLog("<Importação> realidada: <<" + contatosValidos.size() + ">>  contatos  com  sucesso,<<" + (contatosInvalidos.getContatosInvalidos().size() - contAnts)
                + ">> incompletos,<<" + dataHora.getHora() + ">>,<<" + dataHora.getData()
                + ">>,<<" + this.usuario.getNomeUsuario() + ">>.");
        return contatosValidos;
    }

//------------------------Métodos de Impotação do XML-------------------------
    public void importar() throws FileNotFoundException, IllegalAccessException, InstantiationException, ClassNotFoundException, IOException {
        try {
            if (!caminho.equals("")) {
                importarXML(caminho);
                carregando = false;
                JOptionPane.showMessageDialog(null, "Dados XML Importados com Sucesso !!");
                caminho = "";
                view.getBtnProcurar().setText("Procurar");
            } else {
                throw new Exception("Selecione um Arquivo XML antes de importar");
            }
        } catch (FileNotFoundException ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage());
            contatos.gravarLog("Falha:" + ex.getMessage() + " durante a <<Importação>>" + dataHora.getHora() + ">>,<<" + dataHora.getData()
                    + ">>,<<" + this.usuario.getNomeUsuario() + ">>.");
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null, ex);
            contatos.gravarLog("Falha:" + ex.getMessage() + " durante a <<Importação>>" + dataHora.getHora() + ">>,<<" + dataHora.getData()
                    + ">>,<<" + this.usuario.getNomeUsuario() + ">>.");
        }
    }

    public void importarXML(String link) throws FileNotFoundException, Exception {
        File caminho = new File(link);
        Scanner scan = new Scanner(caminho);
        String linha = "";

        long inicio = System.currentTimeMillis();
        long fim = System.currentTimeMillis();
        while (scan.hasNextLine() && (fim - inicio) < 3000 ) {
            linha += scan.nextLine();
            fim = System.currentTimeMillis();
            numLinhas++;
        }
        if(fim - inicio > 3000){
            throw new Exception("Excedeu tempo limite de Importação");
        }
        linha = linha.replace("<contatos>", "<list>");
        linha = linha.replace("<contato>", "<pessoas.model.Contato>");
        linha = linha.replace("<Nome>", "<nome>");
        linha = linha.replace("<Telefone>", "<telefone>");
        linha = linha.replace("<Id>", "<id>");
        linha = linha.replace("</contatos>", "</list>");
        linha = linha.replace("</contato>", "</pessoas.model.Contato>");
        linha = linha.replace("</Nome>", "</nome>");
        linha = linha.replace("</Telefone>", "</telefone>");
        linha = linha.replace("</Id>", "</id>");
        linha = linha.replace(") ", ")");
        lerXML(linha);
    }

    public void lerXML(String xml) throws Exception {

        XStream parser = new XStream(new DomDriver());
        parser.setMode(XStream.NO_REFERENCES);

        ArrayList<Contato> listaXML = (ArrayList<Contato>) parser.fromXML(xml);
        contatos.addContatoArrayList(verificacaoDeImportacao(separaSobrenome(listaXML)));

    }

    public ArrayList<Contato> separaSobrenome(ArrayList<Contato> lista) {
        for (int i = 0; i < lista.size(); i++) {
            if (lista.get(i).getSobrenome() == null) {
                String nomes[] = lista.get(i).getNome().split(" ");
                lista.get(i).setNome(nomes[0]);
                lista.get(i).setSobrenome(nomes[1]);
                if (nomes.length > 2) {
                    String sobre = "";
                    for (int j = 1; j < nomes.length; j++) {
                        sobre += nomes[j] + " ";
                    }
                    lista.get(i).setSobrenome(sobre);
                }
            }
        }
        return lista;
    }

}
